package net.sf.rose.spring;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import net.sf.rose.api.InterfaceClassBean;
import net.sf.rose.api.InterfaceMethodBean;
import net.sf.rose.api.InterfaceMethodParamBean;
import net.sf.rose.api.annotation.InterfaceClass;
import net.sf.rose.api.annotation.InterfaceMethod;
import net.sf.rose.api.annotation.RequestParam;
import net.sf.rose.jdbc.bean.annotation.Table;
import net.sf.rose.jdbc.service.Service;
import net.sf.rose.util.DataUtils;
import net.sf.rose.web.util.SessionUtils;

/**
 * 
 * @author fengjian
 * Spring启动时执行顺序
 * 1、@SpringRegistryUtils
 * 2、@FileWebMvcConfigurerAdapter
 * 3、@ApplicationUtils
 * 此类负责：
 * 1、公共使用的一些配置参数的获取
 * 2、扫描数据库实体类
 */
@Configuration
public class ApplicationUtils implements ApplicationListener<ContextRefreshedEvent> {

	private static ApplicationContext applicationContext;

	/** 所有的接口定义  */
	protected static List<InterfaceClassBean> InterfaceDefineList = new ArrayList<>();

    /**
     * 获取Spring的applicationContext实例
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 获取Spring的applicationContext实例中的环境参数
     * @return
     */
    public static String getEnvironmentProperty(String key) {
        return applicationContext.getEnvironment().getProperty(key);
    }

	/**
	 * 获取所有的接口定义
	 * @return
	 */
	public static List<InterfaceClassBean> getInterfaceDefineList() {
		return InterfaceDefineList;
	}

	/**
     * 获取Spring MVC注解定义的类实例
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		applicationContext = event.getApplicationContext();
		// 扫描所有的接口API定义
		/// scanAllInterfaceDefine();
		// Session缓存控制器
		// SessionUtils.initial();
	}

	/**
	 * 通过Spring扫描所有的接口定义
	 */
	private void scanAllInterfaceDefine() {
		// 自动创建表结构
		// 遍历所有Spring扫描到的类，如果是数据库表关系映射类就与数据库同步
		Service service = new Service();
		for (String name : ApplicationUtils.getApplicationContext().getBeanDefinitionNames()) {
			Object obj = ApplicationUtils.getApplicationContext().getBean(name);
			Class<?> clazz = obj.getClass();
			// 数据库实体类
			if (clazz.getAnnotation(Table.class) != null) {
				// 从实体类中获取表结构定义
				// service.getTableBean(clazz);
			}
			// API接口类
			else {
				String str = clazz.getName();
				// 只接受指定包路径下的Action接口方法的定义
				if (!str.startsWith("com.business.action")) {
					continue;
				}
				// 去掉被代理的后缀，只留下原生的类名
				int index = str.indexOf("$$");
				if (index != -1) {
					str = str.substring(0, index);
				}
				// 重新对这个类的注解作处理
				clazz = DataUtils.forName(str);
				Controller c = clazz.getAnnotation(Controller.class);
				if (c != null) {
					// 接口类注解
					InterfaceClassBean it = new InterfaceClassBean();
					it.setName(clazz.getName());
					RequestMapping r = clazz.getAnnotation(RequestMapping.class);
					if (r != null) {
						it.setRequestMapping(r.value()[0]);
					}
					InterfaceClass i = clazz.getAnnotation(InterfaceClass.class);
					// 如果没有人工定义接口类的说明，则放弃
					if (i == null) {
						continue;
					}
					it.setTitle(i.title());
					it.setDescription(i.description());
					it.setSequence(i.sequence());
					// 接口方法注解
					for (Method m : clazz.getMethods()) {
						RequestMapping mr = m.getAnnotation(RequestMapping.class);
						if (mr != null) {
							InterfaceMethodBean mb = new InterfaceMethodBean();
							mb.setRequestMapping(it.getRequestMapping() + mr.value()[0]);
							mb.setName(m.getName());
							InterfaceMethod im = m.getAnnotation(InterfaceMethod.class);
							// 如果没有人工定义接口方法的说明，则放弃
							if (im == null) {
								continue;
							}
							mb.setTitle(im.title());
							mb.setDescription(im.description());
							mb.setSequence(im.sequence());
							it.getMethods().add(mb);
							// 接口方法的参数描述
							RequestParam rq = m.getAnnotation(RequestParam.class);
							if (rq != null) {
								String val = rq.value();
								if (val.indexOf("},{") != -1) {
									String[] arr = StringUtils.split(val, "},{");
									for (String s : arr) {
										val = StringUtils.remove(s, '{');
										val = val.trim();
										InterfaceMethodParamBean p = new InterfaceMethodParamBean();
										int j = val.indexOf(',');
										p.setName(val.substring(0, j));
										val = val.substring(j + 1);
										j = val.indexOf(',');
										p.setType(val.substring(0, j));
										val = val.substring(j + 1);
										p.setDescription(val);
										mb.getParams().add(p);
									}
								} else {
									val = StringUtils.remove(val, '{');
									val = StringUtils.remove(val, '}');
									val = val.trim();
									InterfaceMethodParamBean p = new InterfaceMethodParamBean();
									int j = val.indexOf(',');
									p.setName(val.substring(0, j));
									val = val.substring(j + 1);
									j = val.indexOf(',');
									p.setType(val.substring(0, j));
									val = val.substring(j + 1);
									p.setDescription(val);
									mb.getParams().add(p);
								}
							}
						}
					}
					// 对所有的方法定义排序
					Collections.sort(it.getMethods(), new Comparator<InterfaceMethodBean>() {
						public int compare(InterfaceMethodBean h1, InterfaceMethodBean h2) {
							return h1.getSequence() - h2.getSequence();
						}
					});
					InterfaceDefineList.add(it);
				}
			}
		}
		// 对所有的接口类定义排序
		Collections.sort(InterfaceDefineList, new Comparator<InterfaceClassBean>() {
			public int compare(InterfaceClassBean h1, InterfaceClassBean h2) {
				return h1.getSequence() - h2.getSequence();
			}
		});
	}
}
